<?php

namespace App\Services\RewardGoldPrize;

use App\Models\User;
use App\Models\GoldRecord;
use Brick\Math\RoundingMode;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;

class RewardTeamParents
{
	protected User $user;

	protected GoldRecord $goldRecord;

	protected Collection $targetParents;

	protected function setParams(GoldRecord $record)
	{
		$this->user = $record->user;
		$this->goldRecord = $record;
		$this->targetParents = $this->user->myTargetGoldPrizeParents();
	}

	protected function canParentReceivePrize(User $parent): bool
	{
		if ($this->goldRecord->isRewarded()) {
            return false;
        } elseif (! $parent->isValidGoldMaster()) {
            return false;
        } elseif (! $this->wasParentInSameRound($parent)) {
            return false;
        } else {
            return true;
        }
	}

    protected function wasParentInSameRound(User $parent): bool
    {
        return $parent->goldRecords()
            ->where('gold_round_id', $this->goldRecord->gold_round_id)
            ->whereDate('created_at', $this->goldRecord->created_at)
            ->whereNotNull('paid_at')
            ->exists();
    }

	protected function rewardFromPercent(GoldRecord $record)
	{
		$prizePercent = big_decimal(cs('storm')->child_record_give_team_parent_masters_prize_percent);
		if ($prizePercent->isLessThanOrEqualTo(0)) {
			return big_decimal(0);
		}

		return big_decimal($record->pay_net_price)
			->multipliedBy($prizePercent->multipliedBy(0.01))
			->toScale(2, RoundingMode::HALF_UP);
	}

	protected function currentParent()
	{
		$user = $this->user;
		$lastRewardedUserId = $user->fresh()->last_team_prize_user_id;
		$parents = $this->targetParents;

		$currentParent = null;

		if ($lastRewardedUserId > 0) {
			$parents = $parents->sortByDesc('id');
			$currentParent = $parents->firstWhere('id', '<', $lastRewardedUserId);
		}

		if ($currentParent) {
			return $currentParent;
		} else {
			return isset($parents[0]) ? $parents[0] : null;
		}
	}

	protected function settle()
	{
		DB::transaction(function () {

			$record = $this->goldRecord;

            /**
             * @var User $currentParent
             */
			$currentParent = $this->currentParent();

			if (! $currentParent) return;

			if ($this->canParentReceivePrize($currentParent)) {

				$currentPrize = $this->rewardFromPercent($record);
				if ($currentPrize->isLessThanOrEqualTo(0)) return;

                $data = [
                    'gold_record_id' => $record->id,
                    'from_user_id' => $record->user_id,
                    'last_to_user_id' => $this->user->last_team_prize_user_id,
                    'now_to_user_id' => $currentParent->id,
                ];
                account_coins($currentParent)->plusGoldRecordTeamPrize($currentPrize, $data);
			}

			$this->user->update(['last_team_prize_user_id' => $currentParent->id]);
		});
	}

	public function reward(GoldRecord $record)
	{
		$this->setParams($record);

		if ($this->targetParents->isEmpty()) return;

		$this->settle();
	}
}
